﻿// ----------------------------------------------------------------------
// <author name="Moses Kehengu"/>
// <copyright file="AppConfiguration.cs" company="Futures Group International">
//     Copyright statement. All right reserved
// </copyright>
//
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using GenericTools;
using DataModels.Enumerations;

namespace GenericTools
{
    /// <summary>
    /// Static class that encapsulates application configurations and settings
    /// </summary>
    public static class AppConfiguration
    {
        #region Class Variables
        private static string dbConnectionString;
        private static string dbProviderName;
        private static string applicationName;

        private static string mailServer;
        private static int mailServerPort;
        private static string mailUsername;
        private static string mailPassword;
        private static string mailFrom;

        private static string errorLogEmailAddress;
        private static bool enableErrorLogMail;
        private static string logFileDirectory;

        private static int maximumReportDelay;
        private static int maximumErrorTolerance;
        private static bool m_SameMonthReporting;

        private static int m_ReportingEngineSMSCheckDelay;
        private static string m_CacheDBProviderName;
        private static string m_CacheDBConnectionString;

        private static bool dataCached;
        private static DataAccessMethod dataAccessMethod;
        private static bool useOfflineData;
        private static int offlineDataCacheLifetime;
        
        private static string webServicesURL;
        private static bool addressFound = false;
        private static string iqsmsBlog;
        
        private static string ssisPackageFilename;
        private static string sourceConnectionStringForPackage;
        private static string destinationConnectionStringForPackage;
        private static string sQLCacheDBConnection;
        private static CacheDB cacheDBType;

        private static string cacheDBName;
        private static bool m_EnableStockInformation;
        private static bool m_EnableAutomaticDataMerging;
        private static bool m_OverwriteInAutoMerge;
        private static int m_StockReportID;

        private static string m_DHISBaseUrl;
        #endregion

        #region Constructors
        static AppConfiguration()
        {
            dbConnectionString = @"Data Source=(local)\SQLEXPRESS;Initial Catalog=IQSMS;Integrated Security=True";
            dbProviderName = "System.Data.SqlClient";
            applicationName = "IQSMS";

            mailServer = "smtp.gmail.com";
            mailServerPort = 587;
            mailUsername = "iqsmsreporting";
            mailPassword = "iqsms1023";
            mailFrom = "iqsmsreporting@gmail.com";

            errorLogEmailAddress = "moseskehengu@yahoo.com";
            enableErrorLogMail = true;
            logFileDirectory = @"C:\IQSMS\Log";

            maximumReportDelay = 2;
            maximumErrorTolerance = 3;
            m_ReportingEngineSMSCheckDelay = 2000;
            m_SameMonthReporting = false;

            dataCached = false;
            useOfflineData = false;
            offlineDataCacheLifetime = 4;   // 4 days

            //TODO: Explore the effect of changing this into direct access
            dataAccessMethod = DataAccessMethod.WEB_SERVICES;

            webServicesURL = "http://localhost/IQWebServices/IQService.asmx";
            iqsmsBlog = "http://iqsmstz.blogspot.com";

            cacheDBName = "IQSMS_CacheDB";
            m_EnableStockInformation = false;
            m_EnableAutomaticDataMerging = true;
            m_OverwriteInAutoMerge = true;
            m_StockReportID = 21;
            m_DHISBaseUrl = "https://apps.dhis2.org/demo";
        }
        #endregion

        #region Data Source Connection
        /// <summary>
        /// Gets or sets the connection string
        /// </summary>
        public static string DBConnectionString
        {
            get
            {
                return dbConnectionString;
            }
            set
            {
                dbConnectionString = value;
            }
        }

        /// <summary>
        /// Gets or sets the connection provider name
        /// </summary>
        public static string DBProviderName
        {
            get
            {
                return dbProviderName;
            }
            set
            {
                dbProviderName = value;
            }
        }

        /// <summary>
        /// Gets or sets the CacheDB connection provider name
        /// </summary>
        public static string CacheDBProviderName
        {
            get
            {
                return m_CacheDBProviderName;
            }
            set
            {
                m_CacheDBProviderName = value;
            }
        }

        /// <summary>
        /// Gets or sets the connection Connection string
        /// </summary>
        public static string CacheDBConnectionString
        {
            get
            {
                return m_CacheDBConnectionString;
            }
            set
            {
                m_CacheDBConnectionString = value;
            }
        }
        #endregion

        #region Mail Server Configurations
        /// <summary>
        /// Gets or Sets the address of the mail server
        /// </summary>
        public static string MailServer
        {
            get
            {
                return mailServer;
            }
            set
            {
                mailServer = value;
            }
        }

        /// <summary>
        /// Gets or sets the port number of the mail server
        /// </summary>
        public static int MailServerPort
        {
            get
            {
                return mailServerPort;
            }
            set
            {
                mailServerPort = value;
            }
        }

        /// <summary>
        /// Gets or sets the email username
        /// </summary>
        public static string MailUsername
        {
            get
            {
                return mailUsername;
            }
            set
            {
                mailUsername = value;
            }
        }

        /// <summary>
        /// Gets or sets the password of the user sending an e-mail
        /// </summary>
        public static string MailPassword
        {
            get
            {
                return mailPassword;
            }
            set
            {
                mailPassword = value;
            }
        }

        /// <summary>
        /// Gets or sets the email of the sender
        /// </summary>
        public static string MailFrom
        {
            get
            {
                return mailFrom;
            }
            set
            {
                mailFrom = value;
            }
        }
        #endregion

        #region Error Logging E-mail Configurations
        /// <summary>
        /// Gets or Sets true or false as to whether to send error log emails or not
        /// </summary>
        public static bool EnableErrorLogMail
        {
            get
            {
                return enableErrorLogMail;
            }
            set
            {
                enableErrorLogMail = value;
            }
        }

        /// <summary>
        /// Gets or Sets the email address where to send error reports
        /// </summary>
        public static string ErrorLogEmailAddress
        {
            get
            {
                return errorLogEmailAddress;
            }
            set
            {
                errorLogEmailAddress = value;
            }
        }

        /// <summary>
        /// Gets or Sets log file directory
        /// </summary>
        public static string LogFileDirectory
        {
            get
            {
                return logFileDirectory;
            }
            set
            {
                logFileDirectory = value;
            }
        }
        #endregion

        #region Other Application Settings
        /// <summary>
        /// Gets or Sets the application name
        /// </summary>
        public static string ApplicationName
        {
            get
            {
                return applicationName;
            }
            set
            {
                applicationName = value;
            }
        }

        /// <summary>
        /// Gets or Sets the maximum allowed years for report dalay. Greater than that system won't allow it.
        /// </summary>
        public static int MaximumReportDelay
        {
            get
            {
                return maximumReportDelay;
            }
            set
            {
                maximumReportDelay = value;
            }
        }

        public static int MaximumErrorTolerance
        {
            get
            {
                return maximumErrorTolerance;
            }
            set
            {
                maximumErrorTolerance = value;
            }
        }

        public static bool DataCached
        {
            get
            {
                return dataCached;
            }
            set
            {
                dataCached = value;
            }
        }

        public static bool UseOfflineData
        {
            get
            {
                return useOfflineData;
            }
            set
            {
                useOfflineData = value;
            }
        }

        public static int OfflineDataCacheLifetime
        {
            get
            {
                return offlineDataCacheLifetime;
            }
            set
            {
                offlineDataCacheLifetime = value;
            }
        }

        public static int ReportingEngineSMSCheckDelay
        {
            get
            {
                return m_ReportingEngineSMSCheckDelay;
            }
            set
            {
                m_ReportingEngineSMSCheckDelay = value;
            }
        }

        //public static string SSISPackageFilename
        //{
        //    get
        //    {
        //        return ssisPackageFilename;
        //    }
        //    set
        //    {
        //        ssisPackageFilename = value;
        //    }
        //}

        //public static string SourceConnectionStringForPackage
        //{
        //    get
        //    {
        //        return sourceConnectionStringForPackage;
        //    }
        //    set
        //    {
        //        sourceConnectionStringForPackage = value;
        //    }
        //}

        //public static string DestinationConnectionStringForPackage
        //{
        //    get
        //    {
        //        return destinationConnectionStringForPackage;
        //    }
        //    set
        //    {
        //        destinationConnectionStringForPackage = value;
        //    }
        //}

        public static string SQLCacheDBConnection
        {
            get
            {
                return sQLCacheDBConnection;
            }
            set
            {
                sQLCacheDBConnection = value;
            }
        }

        public static CacheDB CacheDBType
        {
            get
            {
                return cacheDBType;
            }
            set
            {
                cacheDBType = value;
            }
        }

        public static bool SameMonthReporting
        {
            set
            {
                m_SameMonthReporting = value;
            }
            get
            {
                return m_SameMonthReporting;
            }
        }

        public static bool EnableStockInformation
        {
            set
            {
                m_EnableStockInformation = value;
            }
            get
            {
                return m_EnableStockInformation;
            }
        }

        public static int StockReportID
        {
            get
            {
                return m_StockReportID;
            }
            set
            {
                m_StockReportID = value;
            }
        }

        public static bool EnableAutomaticDataMerging
        {
            get
            {
                return m_EnableAutomaticDataMerging;
            }
            set
            {
                m_EnableAutomaticDataMerging = value;
            }
        }

        public static bool OverwriteInAutoMerge
        {
            get
            {
                return m_OverwriteInAutoMerge;
            }
            set
            {
                m_OverwriteInAutoMerge = value;
            }
        }

        private static bool _IsRunningDemo = false;
        public static bool IsRunningDemo
        {
            get
            {
                return _IsRunningDemo;
            }
            set
            {
                _IsRunningDemo = value;
            }
        }
        #endregion

        #region Data Source Access
        public static DataAccessMethod AccessMethod
        {
            get
            {
                return dataAccessMethod;
            }
            set
            {
                dataAccessMethod = value;
            }
        }

        public static string WebServiceURL
        {
            get
            {
                return webServicesURL;
            }
            set
            {
                webServicesURL = value;
            }
        }

        public static bool AddressFound
        {
            get
            {
                return addressFound;
            }
        }

        public static string IQSMSBlog
        {
            get
            {
                return iqsmsBlog;
            }
            set
            {
                iqsmsBlog = value;
                addressFound = false;
            }
        }

        public static string CacheDBName
        {
            get
            {
                return cacheDBName;
            }
            set
            {
                cacheDBName = value;
            }
        }

        public static string DHISBaseUrl
        {
            get
            {
                return m_DHISBaseUrl;
            }
            set
            {
                m_DHISBaseUrl = value;
            }
        }
        #endregion

        /// <summary>
        /// This method was created to deal with the changing IP address which is 
        /// stored in the configuration file. The current address is blog pages 
        /// under meta content called description.
        /// </summary>
        public static void DetermineWebserviceAddress()
        {
            if (_IsRunningDemo)
            {
                addressFound = true;
                return;
            }

            string url = "http://iqsmstz.blogspot.com/";
            if (!String.IsNullOrEmpty(iqsmsBlog)) url = iqsmsBlog;

            string output = string.Empty;
            try
            {
                WebRequest request = WebRequest.Create(url);
                WebResponse response = request.GetResponse();
                Stream inputStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(inputStream);
                output = reader.ReadToEnd();
            }
            catch
            {
                addressFound = false;
                return;
            }

            try
            {               
                string address = string.Empty;
                int currentIndex = 0;
                string seachText = "<meta content='http://";
                currentIndex = output.IndexOf(seachText);
                if (currentIndex != -1)
                {
                    string lastText = "/>";
                    int endIndex = output.IndexOf(lastText, currentIndex);
                    string meta = output.Substring(currentIndex, endIndex + 2 - currentIndex); //meta tag
                    
                    int addressStartIndex = meta.IndexOf("http://");
                    int addressEndIndex = meta.IndexOf("'", addressStartIndex);
                    //int addressEndIndex = meta.Substring(addressStartIndex).IndexOf("'");
                    address = meta.Substring(addressStartIndex, addressEndIndex-addressStartIndex);
                }

                //throw new NotImplementedException("Refractory Errors");
                if (!String.IsNullOrEmpty(address))
                {
                    webServicesURL = address;
                    addressFound = true;
                    Utilities.WebServicesURL = webServicesURL;
                }
                else
                {
                    addressFound = false;
                    Utilities.WebServicesURL = webServicesURL;
                }
            }
            catch (Exception ex)
            {
                Utilities.LogError(ex, null);
                addressFound = false;
            }
        }
    }
}
